package com.jml.二期.ArrayList001.ext;

import java.util.Arrays;


public class JmlArraylist<E> implements JmlList<E> {
	
	/**
	 * elementData数据存放我们Arraylist所有的数据 transient作用不能序列化
	 */
	transient Object[] elementData; // non-private to simplify nested class access
	/**
	 * 给我们的数组容量赋值为空
	 */
	private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
	/*
	 * 数组的容量默认大小为0
	 */
	private int size;
	
	/**
	 * 数组默认容量大小
	 */
	private static final int DEFAULT_CAPACITY = 10;
	/**
	 * 2的32次方-8
	 */
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	
	public JmlArraylist() {
		// 给我们的数组容量赋值为空
		this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
	}
	
	@Override
	public int size() {
		return size;
	}
	
	@Override
	public boolean add(E e) {
		// 对我们的数组实现扩容
		ensureCapacityInternal(size + 1);
		// 对我们的数据的元素赋值
		elementData[size++] = e;
		return true;
	}
	
	@Override
	public E get(int index) {
		//从数组中查询到数据
		return (E) elementData[index];
	}
	
	@Override
	public E remove(int index) {
		// 检查我们的下标位置是否越界
		rangeCheck(index);
		// 获取要删除的对象
		E oldValue = get(index);
		//计算移动的位置
		int numMoved = size - index - 1;
		// 判断如果删除数据的时候 不是最后一个的情况下，将删除后面的数据往前移动一位
		if (numMoved > 0) {
			System.arraycopy(elementData, index + 1, elementData, index,
					numMoved);
		}
		// 如果numMoved 为0的情况下，说明后面不需要往前移动，直接将最后一条数据赋值为null
		elementData[--size] = null; // clear to let GC do its work
		return null;
	}
	
	private void rangeCheck(int index) {
		if (index >= size) {
			throw new IndexOutOfBoundsException("下标位置越界啦index:" + index);
		}
	}
	
	private void ensureCapacityInternal(int minCapacity) {
		// 添加元素的时候 如果我们数组是为空的请看下
		if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
			//DEFAULT_CAPACITY =10；   minCapacity=0+1  DEFAULT_CAPACITY=10 10>1
			//minCapacity=10;
			minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
		}
		ensureExplicitCapacity(minCapacity);
	}
	
	// modCount++; 增删改的时候  modCount++
	private void ensureExplicitCapacity(int minCapacity) {
		// 10- 数组长度 （0） 10-0 >0 作
		if (minCapacity - elementData.length > 0) {
			// 对我们的数组实现扩容
			grow(minCapacity);
		}
	}
	
	//数组扩容 length 和size有啥
	private void grow(int minCapacity) {
		// 获取我们的数组的长度 old原来的 new  新的 原来数组容量 0；
		int oldCapacity = elementData.length;
		// 新的容量=原来的容量+原来的容量/2 = 0  (原来容量的1.5倍)
		int newCapacity = oldCapacity + (oldCapacity >> 1);
		// 新的容量(0)-最小的容量（10） <0  -10
		//首次添加元素，1.5倍的容量少于新容量，此时用容量大的那个
		if (newCapacity - minCapacity < 0) {
			// 新的容量=10 作用：第一次对我们数组多初始化容量操作
			newCapacity = minCapacity;
		}
		// 判断我们扩容长度大于Integer 21 最大值的情况下
		// 限制我们数组扩容最大值
		if (newCapacity - MAX_ARRAY_SIZE > 0) {
			newCapacity = hugeCapacity(minCapacity);
		}
		//  开始对我们的数组实现扩容 对我们的数据实现扩容 （newCapacity） 将旧的数组数据复制到新的数组中
		elementData = Arrays.copyOf(elementData, newCapacity);
	}
	//(oldCapacity >> 1)  oldCapacity >> 1=oldCapacity/2 010101
	
	/**
	 * 判断我们最小的初始化容量
	 *
	 * @param minCapacity minCapacity==最小的容量>Integer 21 最大值的情况下  Integer.MAX_VALUE
	 * @return
	 */
	private static int hugeCapacity(int minCapacity) {
		if (minCapacity < 0) { // overflow
			throw new OutOfMemoryError();
		}
		return (minCapacity > MAX_ARRAY_SIZE) ?
				Integer.MAX_VALUE :
				MAX_ARRAY_SIZE;
	}
	// 数组做大容量 就是     Integer.MAX_VALUE
	// 红黑树不属于算法  比较抽象的
	/**
	 * 高数
	 */
	
}
